home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / include / scribus-ng / fonts / scface.h < prev    next >
Encoding:
C/C++ Source or Header  |  2009-08-25  |  12.6 KB  |  385 lines

  1. #ifndef SC_FACE_H
  2. #define SC_FACE_H
  3.  
  4. /* ScFace responsibilities:
  5.  
  6. font storage: type, format, filepath, index, document-local, substitute, etc.
  7. usage:        use, embed, subset, ...
  8. face info:    family, effect, alternative, flags, charset
  9. encoding:     CMap2String, glyphnames, 
  10. metrics:      cwidth, bearing, bbox, "real" widths, paths
  11. opentype:     apply features, script support (-)
  12. embedding:    fontdictionary, rawdata, embedPS, embedPDF, subsetPS, subsetPDF
  13. virtual:      dispatch to constituents, handle embedding (-)
  14. */
  15.  
  16. #include <QString>
  17. //#include <QVector>
  18. #include <QMap>
  19. //#include <QArray>
  20. #include <utility>
  21.  
  22. #include "fpointarray.h"
  23.  
  24.  
  25.  
  26. struct GlyphMetrics {
  27.     qreal width;
  28.     qreal ascent;
  29.     qreal descent;
  30. };
  31.  
  32.  
  33.  
  34. /*! \brief Base Class ScFace : This is a total rewrite of the old Foi class.
  35.  
  36. It uses a shared private implementation which must be a subclass of ScFontData.
  37. ScFace objects are quite small and can be handled like value objects. Reference
  38. counting ensures that the shared data is freed when the last ScFace object is
  39. destructed.
  40.  
  41. ScFaceData has caches for face and glyph data. load() fills those caches for
  42. face data, loadGlyph() fills the cache for glyphs. caches are always filled by
  43. need, so you can call unload() any time (well, better not multithreaded...)
  44. without producing errors. the increaseUsage() and decreaseUsage() keep track
  45. of at how many places a face is used and automatically unload when the count 
  46. reaches zero.
  47. Other data is recalculated on demand. The implementation can choose to do its
  48. own caching for this data.
  49.  
  50. ScFace uses a sophisticated lifecycle which controls the state of initialisation
  51. and the performed checks. the normal lilecycle goes:
  52.  
  53. UNKNOWN  --load()-->  LOADED  --checkAllGlyphs()--> CHECKED
  54.  
  55. If the face can not be loaded, the status changes to BROKEN.
  56. If only some glyphs can not be loaded, the status changes to 
  57. BROKENGLYPHS. These fonts can still be used  and subsetted(outlined),
  58. but not embedded.
  59.  
  60. ScFace constructors are only accessible to the ScFonts class which does
  61. some checking before creating a new ScFace. These checks are recorded
  62. in a cache and only reexecuted if the font file changes.
  63. The field 'cachedStatus' allows load() to switch directly to one of the
  64. states BROKEN, CHECKED or BROKENGLYPHS if this state was reached during a
  65. previous run of Scribus.
  66. */
  67. class SCRIBUS_API ScFace
  68. {
  69. public:
  70.     enum Status  { UNKNOWN, LOADED, CHECKED, BROKENGLYPHS, BROKEN, NULLFACE };
  71.     enum FontType { TYPE0, TYPE1, TYPE3, TTF, CFF, OTF, UNKNOWN_TYPE };
  72.     enum FontFormat { PFA, PFB, TYPE2, TYPE42,
  73.         // handled by freetype:    PFB_MAC, DFONT, HQX, MACBIN,
  74.         SFNT, TTCF, UNKNOWN_FORMAT };
  75.  
  76.     static const uint CONTROL_GLYPHS = 2000000000; // 2 billion
  77.     
  78.     struct GlyphData { 
  79.         FPointArray Outlines;
  80.         qreal x;
  81.         qreal y;
  82.         qreal bbox_width;
  83.         qreal bbox_ascent;
  84.         qreal bbox_descent;
  85.         bool broken;
  86.         GlyphData() : Outlines(), x(0), y(0), bbox_width(1), bbox_ascent(1), bbox_descent(0), broken(true) {}
  87.     };
  88.     
  89.     
  90.     /// see accessors for ScFace for docs
  91.     class ScFaceData {
  92.     public:
  93.         /// controls destruction
  94.         mutable int refs;
  95.         /// controls load()
  96.         mutable int usage;
  97.         
  98.         QString scName;
  99.         QString fontFile;
  100.         int     faceIndex;
  101.         QString psName;
  102.         QString family;
  103.         QString style;
  104.         QString variant;
  105.  
  106.         QString forDocument;
  107.  
  108.         mutable ScFace::Status status;
  109.         ScFace::FontType typeCode;
  110.         ScFace::FontFormat formatCode;
  111.         
  112.         bool usable;
  113.         bool embedPs;
  114.         bool subset;
  115.         
  116.         bool isStroked;
  117.         bool isFixedPitch;
  118.         bool hasNames;
  119.         uint maxGlyph;
  120.  
  121.         ScFaceData();
  122.         virtual ~ScFaceData() { };
  123.     protected:
  124.             
  125.         friend class ScFace;
  126.         Status cachedStatus;
  127.         
  128.         // caches
  129.         mutable QMap<uint,qreal>    m_glyphWidth;
  130.         mutable QMap<uint,GlyphData> m_glyphOutline;
  131.         mutable QMap<uint, uint>     m_cMap;
  132.         
  133.         // fill caches & members
  134.         
  135.         virtual void load()             const 
  136.         { 
  137.             m_glyphWidth.clear();
  138.             m_glyphOutline.clear();
  139.             m_cMap.clear();
  140.  
  141.             status = qMax(cachedStatus, ScFace::LOADED);
  142.         }
  143.         
  144.         virtual void unload()           const 
  145.         {
  146.             m_glyphWidth.clear();
  147.             m_glyphOutline.clear();
  148.             m_cMap.clear();
  149.  
  150.             status = ScFace::UNKNOWN;
  151.         }
  152.         
  153.         virtual void loadGlyph(uint /*gl*/) const {}
  154.  
  155.         // dummy implementations
  156.         virtual qreal ascent(qreal sz)           const { return sz; }
  157.         virtual QString ascentAsString()    const { return "0" ; }
  158.         virtual QString descentAsString()    const { return "0"; }
  159.         virtual QString capHeightAsString()    const { return "0"; }
  160.         virtual QString FontBBoxAsString()    const { return "0 0 0 0"; }
  161.         virtual QString ItalicAngleAsString()    const { return "0"; }
  162.         virtual qreal descent(qreal /*sz*/)          const { return 0.0; }
  163.         virtual qreal xHeight(qreal sz)          const { return sz; }
  164.         virtual qreal capHeight(qreal sz)        const { return sz; }
  165.         virtual qreal height(qreal sz)           const { return sz; }
  166.         virtual qreal strikeoutPos(qreal sz)     const { return sz / 2; }
  167.         virtual qreal underlinePos(qreal /*sz*/)     const { return -1.0; }
  168.         virtual qreal strokeWidth(qreal /*sz*/)      const { return 0.1; }
  169.         virtual qreal maxAdvanceWidth(qreal sz)  const { return sz; }
  170.         virtual uint   char2CMap(QChar /*ch*/)         const { return 0; }
  171.         virtual qreal glyphKerning(uint gl1, uint gl2, qreal sz) const;
  172.         virtual QMap<QString,QString> fontDictionary(qreal sz=1.0) const;
  173.         virtual GlyphMetrics glyphBBox(uint gl, qreal sz) const;
  174.         virtual bool EmbedFont(QString &/*str*/)       const { return false; }
  175.         virtual void RawData(QByteArray & /*bb*/)      const {}
  176.         virtual bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList) const;
  177.  
  178.         // these use the cache:
  179.         virtual qreal      glyphWidth(uint gl, qreal sz)   const;
  180.         virtual FPointArray glyphOutline(uint gl, qreal sz) const; 
  181.         virtual FPoint      glyphOrigin (uint gl, qreal sz) const;
  182.         
  183.     };
  184.         
  185.     
  186.     
  187.     ScFace();
  188.     ScFace(const ScFace& other);
  189.     ~ScFace();
  190.  
  191.     /// used as a null object
  192.     static const ScFace& none();
  193.  
  194.     /// test for null object
  195.     bool isNone() const   { return m->status == NULLFACE; }
  196.     
  197.     ScFace& operator=(const ScFace& other);
  198.     /** two ScFaces are equal if they either are both NULLFACEs or they
  199.         agree on family, style, variant and fontpath
  200.         */
  201.     bool operator==(const ScFace& other) const ;
  202.     bool operator!=(const ScFace& other) const { return ! (*this == other); }
  203.     
  204.     
  205.     bool EmbedFont(QString &str);
  206.     void RawData(QByteArray & bb);
  207.     bool glyphNames(QMap<uint, std::pair<QChar, QString> >& gList);
  208.     
  209.     /// prevent unloading of face data
  210.     void increaseUsage() const;
  211.     
  212.     /// unload face data if not used any more
  213.     void decreaseUsage() const;
  214.     
  215.     /// unload face data. It will be reloaded on need
  216.     void unload()      const;
  217.     
  218.     /// the name Scribus uses for this font
  219.     QString scName()   const { return replacedName.isEmpty() ? m->scName : replacedName; }
  220.     
  221.     /// the name of the font which was used for replacement
  222.     QString replacementName()   const { return m->scName; }
  223.     
  224.     /// the name of the font which was used for replacement
  225.     QString replacementForDoc()   const { return replacedInDoc; }
  226.     
  227.     /// check if this is a replacement font
  228.     bool isReplacement()   const { return !replacedName.isEmpty(); }
  229.     
  230.     /// makes a repalcement font for font "name" using this fonts data
  231.     ScFace mkReplacementFor(QString name, QString doc) { 
  232.         ScFace result(m); 
  233.         result.replacedName = name; 
  234.         result.replacedInDoc = doc; 
  235.         return result; 
  236.     }
  237.  
  238.     void chReplacementTo(ScFace& other, QString doc) { 
  239.         QString oldName = replacedName;
  240.         (*this) = other;
  241.         replacedName = oldName;
  242.         replacedInDoc = doc; 
  243.     }
  244.     
  245.     /// the name PostScript uses for this font
  246.     QString psName()   const { return m->psName; }
  247.     
  248.     /// the physical location of the fontfile
  249.     QString fontPath() const { return m->faceIndex >= 0 ? QString("%1(%2)").arg(m->fontFile).arg(m->faceIndex+1) : m->fontFile; }
  250.     
  251.     /// the file path of the fontfile
  252.     QString fontFilePath()      const { return m->fontFile; }
  253.     
  254.     /// if the fontfile contains more than one face, the index, else -1
  255.     int faceIndex()    const { return m->faceIndex; }
  256.     
  257.     /// path name of the document this face is local to
  258.     QString localForDocument()  const { return m->forDocument; }
  259.     
  260.     /// font type, eg. Type1 or TTF
  261.     FontType type()    const { return m->typeCode; }
  262.     
  263.     /// font format, which might be a little more complicated
  264.     FontFormat format()const { return m->formatCode; }
  265.     
  266.     /// test if this face can be used in documents
  267.     bool usable()      const { return m->usable && !isNone(); }
  268.     
  269.     /// test if this face can be embedded in PS/PDF
  270.     bool embedPs()     const { return m->embedPs && m->status < BROKENGLYPHS; }
  271.     
  272.     /// test if this face can be embedded as outlines in PS/PDF
  273.     bool subset()      const { return m->subset && m->status < BROKEN; }
  274.     
  275.     void usable(bool flag)   { m->usable = flag; }
  276.     void embedPs(bool flag)  { m->embedPs = flag; }
  277.     void subset(bool flag)   { m->subset = flag; }
  278.     
  279.     /// deprecated? tells if the face has PS names
  280.     bool hasNames()    const { return m->hasNames; }
  281.  
  282.     /// tells if this font is an outline font
  283.     bool isStroked()   const { return m->isStroked; }
  284.  
  285.     /// tells if this font is a fixed pitch font
  286.     bool isFixedPitch()const { return m->isFixedPitch; }
  287.     
  288.     /// tells if this is an OTF/CFF font
  289.     bool isOTF()       const { return m->typeCode == OTF; }
  290.         
  291.     /// returns the highest glyph index in this face
  292.     uint maxGlyph()    const { return m->maxGlyph; }
  293.     
  294.     /// returns the font family as seen by Scribus
  295.     QString family()   const { return m->family; }
  296.     
  297.     /// returns the font style as seen by Scribus (eg. bold, Italic)
  298.     QString style()    const { return m->style; }
  299.     
  300.     /// returns an additional discriminating String for this face
  301.     QString variant()  const { return m->variant; }
  302.     
  303.     // font metrics
  304.     QString ascentAsString()    const { return m->ascentAsString() ; }
  305.     QString descentAsString()    const { return m->descentAsString() ; }
  306.     QString capHeightAsString()    const { return m->capHeightAsString() ; }
  307.     QString FontBBoxAsString()    const { return m->FontBBoxAsString() ; }
  308.     QString ItalicAngleAsString()    const { return m->ItalicAngleAsString() ; }
  309.     qreal ascent(qreal sz=1.0)          const;
  310.     qreal descent(qreal sz=1.0)         const;
  311.     qreal xHeight(qreal sz=1.0)         const;
  312.     qreal capHeight(qreal sz=1.0)       const;
  313.     qreal height(qreal sz=1.0)          const;
  314.     qreal strikeoutPos(qreal sz=1.0)    const;
  315.     qreal underlinePos(qreal sz=1.0)    const;
  316.     qreal strokeWidth(qreal sz=1.0)     const;
  317.     qreal maxAdvanceWidth(qreal sz=1.0) const;
  318.     
  319.     /// deprecated
  320.     QString stemV(qreal sz=1.0)    const { return fontDictionary(sz)["/StemV"]; }
  321.     
  322.     /// deprecated
  323.     QString italicAngle(qreal sz=1.0)      const { return fontDictionary(sz)["/ItalicAngle"]; }
  324.     
  325.     /// deprecated
  326.     QString fontBBox(qreal sz=1.0)         const { return fontDictionary(sz)["/FontBBox"]; }
  327.  
  328.     /// returns a map of values used for font dictionaries in PS/PDF
  329.     QMap<QString,QString> fontDictionary(qreal sz=1.0) const { return m->fontDictionary(sz); }    
  330.     // glyph interface
  331.     
  332.     /// returns the glyphs normal advance width at size 'sz'
  333.     qreal glyphWidth(uint gl, qreal sz=1.0) const { return m->glyphWidth(gl, sz); }
  334.  
  335.     /// returns the glyph kerning between 'gl1' and 'gl2' at size 'sz'
  336.     qreal glyphKerning(uint gl1, uint gl2, qreal sz=1.0) const { return qMax(gl1,gl2) < CONTROL_GLYPHS ? m->glyphKerning(gl1, gl2, sz) : 0; } 
  337.  
  338.     /// returns the glyphs bounding box at size 'sz', ie. the area where this glyph will produce marks
  339.     GlyphMetrics glyphBBox(uint gl, qreal sz=1.0) const { return m->glyphBBox(gl, sz); }
  340.  
  341.     /// returns the glyph's outline as a cubic Bezier path
  342.     FPointArray glyphOutline(uint gl, qreal sz=1.0) const { return m->glyphOutline(gl, sz); }
  343.  
  344.     /// returns the glyph's origin FIXME: what's that exactly?
  345.     FPoint glyphOrigin(uint gl, qreal sz=1.0)    const { return m->glyphOrigin(gl, sz); }
  346.     
  347.     // char interface
  348.  
  349.     /// test if the face can render this char
  350.     bool canRender(QChar ch)   const;
  351.  
  352.     /// translate unicode to glyph index
  353.     uint char2CMap(QChar ch)   const;
  354.  
  355.     /// returns the combined glyph width and kerning for 'ch' if followed by 'ch2'
  356.     qreal charWidth(QChar ch, qreal sz=1.0, QChar ch2 = QChar(0)) const;
  357.     
  358.     /// deprecated, see glyphBBox()
  359.     qreal realCharWidth(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).width; }
  360.     
  361.     /// deprecated, see glyphBBox()
  362.     qreal realCharHeight(QChar ch, qreal sz=1.0) const { GlyphMetrics gm=glyphBBox(char2CMap(ch),sz); return gm.ascent + gm.descent; }
  363.     
  364.     /// deprecated, see glyphBBox()
  365.     qreal realCharAscent(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).ascent; }
  366.     
  367.     /// deprecated, see glyphBBox()
  368.     qreal realCharDescent(QChar ch, qreal sz=1.0) const { return glyphBBox(char2CMap(ch),sz).descent; }
  369.     
  370. private:
  371.         
  372.     friend class SCFonts;
  373.     
  374.     ScFace(ScFaceData* md);
  375.     ScFaceData* m;
  376.     QString replacedName;
  377.     QString replacedInDoc;
  378.     
  379.     void initFaceData();
  380.     void checkAllGlyphs();
  381.     uint emulateGlyph(QChar c) const;
  382. };
  383.  
  384. #endif
  385.